/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package avl.sv.client;

import avl.sv.shared.Solution;
import avl.sv.shared.model.classifier.AbstractClassifier;
import avl.sv.shared.model.classifier.ClassifierLDA;
import avl.sv.shared.model.classifier.ClassifierOptionsPromptInterface;
import avl.sv.shared.model.classifier.ClassifierSVM;
import avl.sv.shared.model.featureGenerator.AbstractFeatureGenerator;
import avl.sv.shared.model.featureGenerator.FeatureGeneratorImageJ;
import avl.sv.shared.model.featureGenerator.FeatureGeneratorOptionsPromptInterface;
import avl.sv.shared.model.featureGenerator.jocl.FeatureGeneratorJOCL;
import ij.gui.MessageDialog;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JMenuItem;

/**
 *
 * @author benbryan
 */
public class ModelSetup extends javax.swing.JDialog {
    final Solution solution;
    private boolean iscanceled = false;

    public class Plugin {

        final String name;
        final Class c;

        public Plugin(String name, Class c) {
            this.name = name;
            this.c = c;
        }
    }
    
    private ArrayList<Plugin> plugins = new ArrayList<>();
    
    public ModelSetup(java.awt.Frame parent, boolean modal, final Solution solution) {
        super(parent, modal);
        initComponents();
        this.solution = solution;
        plugins.add( new Plugin("SVM", ClassifierSVM.class) );
        plugins.add( new Plugin("ImageJ", FeatureGeneratorImageJ.class) );
        plugins.add( new Plugin("JOCL", FeatureGeneratorJOCL.class) );
        plugins.add( new Plugin("LDA", ClassifierLDA.class) );       
    }
    
    private void populateTabData() {
        {
            jTabbedPaneClassifiers.removeAll();
            Iterator<AbstractClassifier> iterClassifier = solution.getClassifierIterator();
            while (iterClassifier.hasNext()) {
                AbstractClassifier classifier = iterClassifier.next();
                jTabbedPaneClassifiers.add(classifier.getName(), classifier.getOptionsPanel());
            }
            jTabbedPaneClassifiers.updateUI();
        }
        {
            jTabbedPaneFeatures.removeAll();
            Iterator<AbstractFeatureGenerator> iterFeatures = solution.getFeatureIterator();
            while (iterFeatures.hasNext()) {
                AbstractFeatureGenerator featureGenerator = iterFeatures.next();
                jTabbedPaneFeatures.add(featureGenerator.getName(), featureGenerator.getOptionsPanel());
            }
            jTabbedPaneFeatures.updateUI();
        }
        pack();
    }
    
    private void collectTabData(){
        {
            Component[] tabs = jTabbedPaneClassifiers.getComponents();
            for (int t = 0; t < tabs.length; t++){
                Component tab = tabs[t];
                if (tab instanceof ClassifierOptionsPromptInterface){
                    AbstractClassifier classifier = ((ClassifierOptionsPromptInterface)tab).getClassifier();
                    solution.setClassifier(classifier);
                    classifier.setActive(true);
                    classifier.invalidate();
                }
            }
        }        
        {
            Component[] tabs = jTabbedPaneFeatures.getComponents();
            for (int t = 0; t < tabs.length; t++){
                Component tab = tabs[t];
                if (tab instanceof FeatureGeneratorOptionsPromptInterface){
                    AbstractFeatureGenerator featureGenerator = ((FeatureGeneratorOptionsPromptInterface)tab).getFeatureGenerator();
                    solution.setFeatureGenerator(featureGenerator);
                    featureGenerator.isactive = true;
                }
            }
        }
    }

    @Override
    public void setVisible(boolean b) {
        if (!b){
            return;
        }
        jMenuClassifier.removeAll();
        jMenuFeatures.removeAll();
        populateTabData();
        for (final Plugin p : plugins) {
            final JMenuItem item = new JMenuItem(p.name);
            if (AbstractClassifier.class.isAssignableFrom(p.c)) {
                item.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        try {
                            Object obj = p.c.newInstance();
                            solution.setClassifier((AbstractClassifier)obj);
                            populateTabData();
                        } catch (InstantiationException | IllegalAccessException ex) {
                            Logger.getLogger(ModelSetup.class.getName()).log(Level.SEVERE, null, ex);
                            MessageDialog md = new MessageDialog(null, "Error", "Failed to create");
                        }
                    }
                });
                jMenuClassifier.add(item);
            } else if (AbstractFeatureGenerator.class.isAssignableFrom(p.c)) {
                item.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        try {
                            Object obj = p.c.newInstance();
                            solution.setFeatureGenerator((AbstractFeatureGenerator)obj);
                            populateTabData();
                        } catch (InstantiationException | IllegalAccessException ex) {
                            Logger.getLogger(ModelSetup.class.getName()).log(Level.SEVERE, null, ex);
                            MessageDialog md = new MessageDialog(null, "Error", "Failed to create");
                        }
                    }
                });
                jMenuFeatures.add(item);
            }
        }
        super.setVisible(b);
    }   
    
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPopupMenuFeatures = new javax.swing.JPopupMenu();
        jMenuItemFeatureDelete = new javax.swing.JMenuItem();
        jPopupMenuClassifiers = new javax.swing.JPopupMenu();
        jMenuItemClassifierDelete = new javax.swing.JMenuItem();
        jMenuItem1 = new javax.swing.JMenuItem();
        jButtonAccept = new javax.swing.JButton();
        jButtonCancel = new javax.swing.JButton();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenuAdd = new javax.swing.JMenu();
        jMenuClassifier = new javax.swing.JMenu();
        jMenuFeatures = new javax.swing.JMenu();

        jMenuItemFeatureDelete.setText("Delete");
        jMenuItemFeatureDelete.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemFeatureDeleteActionPerformed(evt);
            }
        });
        jPopupMenuFeatures.add(jMenuItemFeatureDelete);

        jMenuItemClassifierDelete.setText("Delete");
        jMenuItemClassifierDelete.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemClassifierDeleteActionPerformed(evt);
            }
        });
        jPopupMenuClassifiers.add(jMenuItemClassifierDelete);

        jMenuItem1.setText("jMenuItem1");

        setTitle("Setup Model");
        setLocationByPlatform(true);

        jTabbedPaneMain.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        jTabbedPaneFeatures.setComponentPopupMenu(jPopupMenuFeatures);
        jTabbedPaneMain.addTab("Features", jTabbedPaneFeatures);

        jTabbedPaneClassifiers.setComponentPopupMenu(jPopupMenuClassifiers);
        jTabbedPaneMain.addTab("Classifiers", jTabbedPaneClassifiers);

        jButtonAccept.setText("Accept");
        jButtonAccept.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonAcceptActionPerformed(evt);
            }
        });

        jButtonCancel.setText("Cancel");
        jButtonCancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonCancelActionPerformed(evt);
            }
        });

        jMenuAdd.setText("Add");

        jMenuClassifier.setText("Classifier");
        jMenuAdd.add(jMenuClassifier);

        jMenuFeatures.setText("Features");
        jMenuFeatures.setToolTipText("");
        jMenuAdd.add(jMenuFeatures);

        jMenuBar1.add(jMenuAdd);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jTabbedPaneMain)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(332, Short.MAX_VALUE)
                .addComponent(jButtonCancel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButtonAccept)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jTabbedPaneMain, javax.swing.GroupLayout.DEFAULT_SIZE, 393, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButtonAccept)
                    .addComponent(jButtonCancel))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCancelActionPerformed
        iscanceled = true;
        jTabbedPaneClassifiers.removeAll();
        jTabbedPaneFeatures.removeAll();
        dispose();
    }//GEN-LAST:event_jButtonCancelActionPerformed

    private void jButtonAcceptActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonAcceptActionPerformed
        iscanceled = false;
        collectTabData();
        setVisible(false);
        dispose();
    }//GEN-LAST:event_jButtonAcceptActionPerformed

    private void jMenuItemFeatureDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemFeatureDeleteActionPerformed
        FeatureGeneratorOptionsPromptInterface featureGeneratorOptions = (FeatureGeneratorOptionsPromptInterface) jTabbedPaneFeatures.getSelectedComponent();
        solution.removeFeatureGenerator(featureGeneratorOptions.getFeatureGenerator().getClass());
        jTabbedPaneFeatures.remove(jTabbedPaneFeatures.getSelectedComponent());
    }//GEN-LAST:event_jMenuItemFeatureDeleteActionPerformed

    private void jMenuItemClassifierDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemClassifierDeleteActionPerformed
        ClassifierOptionsPromptInterface temp = (ClassifierOptionsPromptInterface) jTabbedPaneFeatures.getSelectedComponent();
        solution.removeClassifier(temp.getClassifier().getClass());
        jTabbedPaneFeatures.remove(jTabbedPaneFeatures.getSelectedComponent());
    }//GEN-LAST:event_jMenuItemClassifierDeleteActionPerformed

    public boolean iscanceled() {
        return iscanceled;
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonAccept;
    private javax.swing.JButton jButtonCancel;
    private javax.swing.JMenu jMenuAdd;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JMenu jMenuClassifier;
    private javax.swing.JMenu jMenuFeatures;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem jMenuItemClassifierDelete;
    private javax.swing.JMenuItem jMenuItemFeatureDelete;
    private javax.swing.JPopupMenu jPopupMenuClassifiers;
    private javax.swing.JPopupMenu jPopupMenuFeatures;
    private final javax.swing.JTabbedPane jTabbedPaneClassifiers = new javax.swing.JTabbedPane();
    private final javax.swing.JTabbedPane jTabbedPaneFeatures = new javax.swing.JTabbedPane();
    private final javax.swing.JTabbedPane jTabbedPaneMain = new javax.swing.JTabbedPane();
    // End of variables declaration//GEN-END:variables
}
